package com.stx.handler;

public class Handler {

    private static final String TAG = "Handler";
    private static final boolean FIND_POTENTIAL_LEAKS = false;
    private static Handler MAIN_THREAD_HANDLER = null;

    public interface Callback {
        public boolean handleMessage(Message msg);
    }

    private   final Callback mCallback;
    private   final Looper mLooper;
    private   final MessageQueue mQueue;
    private   final boolean mAsynchronous;

    /**
     * 默认构造函数
     */
    public Handler() {
        this(null, false);
    }

    public Handler(Callback callback) {
        this(callback, false);
    }

    public Handler(Looper looper) {
        this(looper, null, false);
    }

    /**
     * 构造函数2
     * @param looper
     * @param callback
     */
    public Handler(Looper looper, Callback callback) {
        this(looper, callback, false);
    }

    public Handler(Callback callback, boolean async) {
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                    "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

    /**
     * 构造函数3
     * @param looper        消息循环
     * @param callback      回调处理
     * @param async         是否同步
     */
    public Handler(Looper looper, Callback callback, boolean async) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }


    /**
     * 消息接受函数, 子类必须覆写该函数
     * @param msg
     */
    public void handleMessage(Message msg) {
    }

    /**
     * 分发消息
     * @param msg
     */
    public void dispatchMessage(Message msg) {
            handleMessage(msg);
    }

    /**
     * 从消息缓存区获取消息
     * @return
     */
    public final Message obtainMessage()
    {
        return Message.obtain(this);
    }

    /**
     * 从消息缓存区获取消息
     * @return
     */
    public final Message obtainMessage(int what)
    {
        return Message.obtain(this, what);
    }

    /**
     * 从消息缓存区获取消息
     * @return
     */
    public final Message obtainMessage(int what, Object obj)
    {
        return Message.obtain(this, what, obj);
    }

    /**
     * 从消息缓存区获取消息
     * @return
     */
    public final Message obtainMessage(int what, int arg1, int arg2)
    {
        return Message.obtain(this, what, arg1, arg2);
    }

    /**
     * 从消息缓存区获取消息
     * @return
     */
    public final Message obtainMessage(int what, int arg1, int arg2, Object obj){
        return Message.obtain(this, what, arg1, arg2, obj);
    }


    /**
     * 发送消息
     * @param msg
     * @return
     */
    public final boolean sendMessage(Message msg){
        return sendMessageDelayed(msg, 0);
    }

    /**
     * 发送空消息延迟
     * @param what
     * @return
     */
    public final boolean sendEmptyMessage(int what){
        return sendEmptyMessageDelayed(what, 0);
    }

    /**
     * 当前延迟发送消息时间
     * @param msg
     * @param delayMillis
     * @return
     */
    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        long currentTime = System.currentTimeMillis();
        return sendMessageAtTime(msg, currentTime + delayMillis);
    }

    /**
     * 发送空消息延迟
     * @param what
     * @param delayMillis
     * @return
     */
    public final boolean sendEmptyMessageDelayed(int what, long delayMillis)
    {
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageDelayed(msg, delayMillis);
    }

    /**
     * 在指定时间发送消息
     * @param what
     * @param uptimeMillis
     * @return
     */
    public boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageAtTime(msg, uptimeMillis);
    }

    /**
     * 在指定时间点发送消息
     * @param msg
     * @param uptimeMillis
     * @return
     */
    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            System.out.println("Looper " + e.getMessage());
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }

    /**
     * 根据消息类型从消息队列中移除消息
     * @param what
     */
    public final void removeMessages(int what){
        mQueue.removeMessages(this, what, null);
    }

    public final void removeMessages(int what, Object obj){
        mQueue.removeMessages(this, what, obj);
    }

    /**
     * 清除消息队列中所有消息
     * @param token
     */
    public final void removeCallbacksAndMessages(Object token) {
        mQueue.removeCallbacksAndMessages(this, token);
    }

    public final boolean hasMessages(int what) {
        return mQueue.hasMessages(this, what, null);
    }


    public final boolean hasMessages(int what, Object object) {
        return mQueue.hasMessages(this, what, object);
    }

    public final Looper getLooper() {
        return mLooper;
    }

    /**
     * 将消息放到消息队列中
     * @param queue
     * @param msg
     * @param uptimeMillis
     * @return
     */
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }
}



